package com.a01_2021.thousandstimes.general.service.impl;

import com.a01_2021.thousandstimes.exception.CustomException;
import com.a01_2021.thousandstimes.exception.CustomExceptionType;
import com.a01_2021.thousandstimes.general.entity.Experience;
import com.a01_2021.thousandstimes.general.mapper.ExperienceMapper;
import com.a01_2021.thousandstimes.general.service.ExperienceService;
import com.a01_2021.thousandstimes.general.service.IExperienceDetailService;
import com.a01_2021.thousandstimes.general.service.SysUserService;
import com.a01_2021.thousandstimes.instance.entity.Position;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author FRQ
 * @since 2021-02-22
 */
@Service
public class ExperienceServiceImpl extends ServiceImpl<ExperienceMapper, Experience> implements ExperienceService {

    @Resource
    ExperienceMapper experienceMapper;

    @Resource
    SysUserService sysUserService;

    @Resource
    IExperienceDetailService experienceDetailService;

    /**
     * 获取当前用户id的对应职位名
     *
     * @param userId 用户id
     * @return title职位名
     * @throws CustomException 当用户不存在时抛出该异常
     */
    @Override
    public String getCurrentTitle(long userId) throws CustomException {
        Experience experience = this.getCurrentExperience(userId);
        if (experience == null) {
            return null;
        }
        return experience.getTitle();
    }

    /**
     * 获取当前用户id的对应职位id
     *
     * @param userId 用户id
     * @return 职位id
     * @throws CustomException 当用户不存在时抛出该异常
     */
    public long getPositionId(long userId) throws CustomException {
        Experience experience = this.getCurrentExperience(userId);
        if (experience == null) {
            return 0;
        }
        return experience.getPositionId();
    }

    /**
     * 通过用户id获取当前经历
     *
     * @param userId 用户id
     * @return 用户当前经历
     * @throws CustomException 当用户不存在时抛出该异常
     */
    public Experience getCurrentExperience(long userId) throws CustomException {
        if (!sysUserService.isUser(userId)) {
            throw new CustomException(CustomExceptionType.USER_NOT_FOUND_ERROR, "找不到该用户");
        }
        QueryWrapper<Experience> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        queryWrapper.isNull("end_date");
        Experience experience = experienceMapper.selectOne(queryWrapper);
        if (experience == null) {
            QueryWrapper<Experience> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("user_id", userId);
            queryWrapper1.orderByDesc("end_date");
            List<Experience> experienceList = experienceMapper.selectList(queryWrapper1);
            if (experienceList.size() == 0) {
                return null;
            } else {
                experience = experienceList.get(0);
            }
        }
        return experience;
    }

    /**
     * 用于添加经历
     *
     * @param experience 经历实体
     * @return 经历实体
     * @throws CustomException 当不存在该用户时抛出该异常
     */
    @Override
    public Experience add(Experience experience) throws CustomException {
        if (!sysUserService.isUser(experience.getUserId())) {
            throw new CustomException(CustomExceptionType.USER_NOT_FOUND_ERROR, "不存在该用户");
        }
        if (experience.getStartDate() == null) {
            throw new CustomException("起始时间不得为空", 400);
        }
        experienceMapper.insert(experience);
        return experience;
    }

    /**
     * 用于获取指定用户的经历
     *
     * @param userId 用户id
     * @return AjaxResponse
     */
    @Override
    public List<Experience> get(long userId) {
        QueryWrapper<Experience> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return experienceMapper.selectList(queryWrapper);
    }

    /**
     * 用于获取指定用户的经历（增加用户存在性校验
     *
     * @param userId 用户id
     * @return AjaxResposne
     * @throws CustomException 当用户不存在时抛出该异常
     */
    @Override
    public List<Experience> getFromUserId(long userId) throws CustomException {
        if (!sysUserService.isUser(userId)) {
            throw new CustomException(CustomExceptionType.USER_NOT_FOUND_ERROR, "该用户不存在");
        }
        return this.get(userId);
    }

    /**
     * 获取当前有效经历id
     *
     * @param userId 用户id
     * @param date   查询当月时间
     * @return 有效经历id
     * @throws CustomException 当用户不存在、无有效经历时抛出该异常
     */
    @Override
    public long getCurrentExperienceId(long userId, LocalDate date) throws CustomException {
        if (!sysUserService.isUser(userId)) {
            throw new CustomException(CustomExceptionType.USER_NOT_FOUND_ERROR, "找不到该用户");
        }
        QueryWrapper<Experience> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        //设置时间区间
        LocalDate startDate = date.minusDays(date.getDayOfMonth() - 1);
        LocalDate endDate = startDate.plusMonths(1);
        //选取经历结束时间位于该月时间内，或为空的经历
        queryWrapper.between("end_date", startDate, endDate).or().isNull("end_date");
        List<Experience> experienceList = experienceMapper.selectList(queryWrapper);
        if (experienceList.size() < 1) {
            throw new CustomException(CustomExceptionType.EXPERIENCE_NOT_FOUND_ERROR, "找不到有效经历");
        }
        return experienceList.get(0).getId();
    }

    /**
     * 获取用户过去经历数量统计
     *
     * @param userId 用户id
     * @return 过去经历数量统计
     */
    @Override
    public int getCount(long userId) {
        QueryWrapper<Experience> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);
        return experienceMapper.selectCount(queryWrapper);
    }

    /**
     * 更换新职位
     *
     * @param userId     用户id
     * @param position   职位实体类
     * @param instanceId 实例id
     * @return Experience
     */
    @Override
    public Experience changePosition(long userId, Position position, long instanceId) throws CustomException {
        //结束上一次经历
        Experience currentExperience = this.getCurrentExperience(userId);
        currentExperience.setEndDate(LocalDate.now());
        currentExperience.setScore(experienceDetailService.getAvgScore(currentExperience.getId()));
        experienceMapper.updateById(currentExperience);
        //开始新经历
        Experience experience = new Experience(null, userId, null, null, null, LocalDate.now(), null, position.getPostId(), position.getId(), position.getName(), instanceId, 0.0);
        experienceMapper.insert(experience);
        return experience;
    }

    /**
     * 通过用户id与实例id获取经历
     *
     * @param userId     用户id
     * @param instanceId 实例id
     * @return List经历列表
     */
    @Override
    public List<Experience> getFromInstanceIdAndUserId(long userId, long instanceId) {
        QueryWrapper<Experience> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("user_id", userId)
                .eq("instance_id", instanceId);
        return experienceMapper.selectList(queryWrapper);
    }

    /**
     * 将经历列表插入主数据库中
     *
     * @param experienceList 经历列表
     * @return Map原经历id与主数据经历id
     */
    @DS("master")
    @Override
    public Map<Long, Long> addIntoMaster(List<Experience> experienceList) {
        Map<Long, Long> map = new HashMap<>();
        for (Experience item : experienceList) {
            Experience experience = new Experience(null, item.getUserId(), null, null, null,
                    item.getStartDate(), item.getEndDate(), item.getPostId(), item.getPositionId(), item.getTitle(),
                    item.getInstanceId(), item.getScore());
            experienceMapper.insert(experience);
            map.put(item.getId(), experience.getId());
        }
        return map;
    }
}
